Skip to content

feat(auth): per-user provider ownership enforcement#19

Merged
pdettori merged 4 commits into
mvp-v2from
feat/per-user-provider-ownership-1995
Jun 17, 2026
Merged

feat(auth): per-user provider ownership enforcement#19
pdettori merged 4 commits into
mvp-v2from
feat/per-user-provider-ownership-1995

Conversation

@pdettori

Copy link
Copy Markdown
Member

Summary

  • Extend the openshell.ai/owner label pattern (from sandbox ownership in feat(auth): per-user sandbox ownership enforcement #18) to providers
  • OIDC-authenticated users can now create/manage their own providers without admin privileges
  • Shared providers (no owner label) remain accessible to all users — fully backwards compatible

Implements kagenti/kagenti#1995 (core enforcement; name-scoping and sandbox-binding alignment deferred to follow-up).

Changes

  • Relax provider CRUD #[rpc_auth] from role = "admin"role = "user" (except ImportProviderProfiles / DeleteProviderProfile)
  • Stamp openshell.ai/owner label on provider create
  • Add check_provider_owner guard to get, update, delete, configure-refresh, rotate-credential, delete-refresh
  • Filter list_providers to own + shared for regular users, all for admins
  • Update authz tests for relaxed role requirements
  • Add 12 ownership isolation unit tests

Test plan

  • All 796 unit tests pass (12 new + 784 existing)
  • Manual test on Kind: create provider as user A, verify user B cannot access
  • Verify shared/legacy providers remain accessible after upgrade

Assisted-By: Claude Code

pdettori added 3 commits June 16, 2026 20:27
Extend the openshell.ai/owner label pattern (from sandbox ownership in
PR #18) to providers, enabling OIDC-authenticated users to create and
manage their own providers on a shared gateway without admin privileges.

Changes:
- Relax provider CRUD methods from admin to user role in rpc_auth
  annotations (ImportProviderProfiles/DeleteProviderProfile remain admin)
- Stamp owner label on provider create via stamp_owner()
- Add ownership checks (check_provider_owner) to get, update, delete,
  configure-refresh, rotate-credential, and delete-refresh handlers
- Filter list_providers to return own + shared for regular users, all
  for admins
- Make ownership.rs docstring entity-generic (shared with sandboxes)
- Update authz tests to reflect relaxed role requirements
- Add 12 ownership isolation unit tests covering create/get/list/update/
  delete with owner, non-owner, admin, and shared provider scenarios

Implements kagenti/kagenti#1995 (partial: Tasks 1-2, 5 complete;
Tasks 3-4 deferred for follow-up).

Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com>
Signed-off-by: Paolo Dettori <dettori@us.ibm.com>
Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com>
Signed-off-by: Paolo Dettori <dettori@us.ibm.com>
When attaching a provider to a sandbox, verify the provider is either
owned by the caller or shared (no owner label). This prevents user A
from referencing user B's private provider in their sandbox.

Adds two tests: one for the rejection case and one confirming shared
providers remain attachable by any user.

Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com>
Signed-off-by: Paolo Dettori <dettori@us.ibm.com>

@pdettori pdettori left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Solid, well-tested authz change extending the openshell.ai/owner label pattern from sandboxes (#18) to providers — RBAC relaxed admin→user with enforcement moved into handlers, admin/anonymous backward-compat preserved.

Blocker: CI is red — the Rust clippy gate fails with 10 -D warnings errors (1 in production code at the list filter, 9 in the new test module). Merge is blocked until clippy is clean: cargo clippy --workspace --all-targets -- -D warnings.

Two non-blocking correctness notes inline (per-user list pagination, and the skip-on-not-found ownership guard in update/delete).

Areas reviewed: Rust authz/ownership/provider/sandbox, tests, CI. 3 commits, all signed-off. No .claude/.vscode changes.

Assisted-By: Claude Code

Comment thread crates/openshell-server/src/grpc/provider.rs Outdated
Comment thread crates/openshell-server/src/grpc/provider.rs Outdated
Comment thread crates/openshell-server/src/grpc/provider.rs Outdated
- Fix clippy warnings: unnecessary qualifications, redundant closures,
  iter_on_single_items, map_or→is_none_or
- Fix list pagination for non-admins: loop in batches to guarantee
  `limit` visible results despite post-fetch filtering
- Align update/delete ownership guards to return NOT_FOUND early when
  the provider doesn't exist, matching get/rotate behavior

Signed-off-by: Paolo Dettori <paolo@dettori.dev>
Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com>
Signed-off-by: Paolo Dettori <dettori@us.ibm.com>
@pdettori pdettori merged commit b3147e9 into mvp-v2 Jun 17, 2026
8 of 10 checks passed
@pdettori pdettori deleted the feat/per-user-provider-ownership-1995 branch June 17, 2026 13:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant